#include <stdio.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <inttypes.h>
#include "HTU31.h"

// 手动校准值设置 - 可根据需要修改这些值
#define TEMPERATURE_CALIBRATION_OFFSET  0.0   // 温度校准偏移量 (°C)
#define HUMIDITY_CALIBRATION_OFFSET     0.0   // 湿度校准偏移量 (%RH)

#define I2C_SDA_PIN GPIO_NUM_5
#define I2C_SCL_PIN GPIO_NUM_4
#define I2C_MASTER_NUM I2C_NUM_0  // I2C端口号
#define I2C_MASTER_FREQ_HZ 100000 // I2C频率：100KHz

static const char *TAG = "HTU31_DEMO";

// I2C初始化函数
static esp_err_t i2c_master_init(void)
{
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_SDA_PIN,
        .scl_io_num = I2C_SCL_PIN,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
        .clk_flags = 0,
    };

    esp_err_t err = i2c_param_config(I2C_MASTER_NUM, &conf);
    if (err != ESP_OK) {
        return err;
    }

    return i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);
}

// 尝试初始化HTU31传感器
static esp_err_t init_htu31_sensor(htu31_handle_t *htu31_handle)
{
    esp_err_t ret;
    
    // 只使用地址0x41
    ESP_LOGI(TAG, "初始化HTU31传感器，地址: 0x%02X", HTU31_I2C_ADDR_2);
    ret = htu31_init(htu31_handle, I2C_MASTER_NUM, HTU31_I2C_ADDR_2);
    if (ret == ESP_OK) {
        ESP_LOGI(TAG, "HTU31传感器初始化成功，使用地址: 0x%02X", HTU31_I2C_ADDR_2);
        return ESP_OK;
    }
    
    ESP_LOGE(TAG, "HTU31传感器初始化失败，地址: 0x%02X", HTU31_I2C_ADDR_2);
    return ret;
}

// 读取并打印传感器数据
static void read_sensor_data(htu31_handle_t *htu31_handle)
{
    htu31_data_t sensor_data;
    
    // 读取序列号（仅在启动时读取一次）
    ESP_LOGI(TAG, "跳过序列号读取，直接读取温湿度数据");
    // uint32_t serial_number;
    // if (htu31_read_serial_number(htu31_handle, &serial_number) == ESP_OK) {
    //     ESP_LOGI(TAG, "HTU31传感器序列号: 0x%08" PRIX32, serial_number);
    // }
    
    // 持续读取温湿度数据
    while (1) {
        ESP_LOGI(TAG, "=== 开始读取数据 ===");
        
        // 尝试正常读取
        esp_err_t ret = htu31_read_temperature_humidity(htu31_handle, &sensor_data);
        
        if (ret == ESP_OK) {
            // 打印温湿度数据
            ESP_LOGI(TAG, "=== HTU31 传感器数据 ===");
            ESP_LOGI(TAG, "温度: %.2f °C (校准偏移量: %.2f °C)", 
                     sensor_data.temperature, htu31_get_temperature_offset(htu31_handle));
            ESP_LOGI(TAG, "湿度: %.2f %%RH (校准偏移量: %.2f %%RH)", 
                     sensor_data.humidity, htu31_get_humidity_offset(htu31_handle));
            ESP_LOGI(TAG, "========================");
            
            // 也可以单独读取温度
            float temperature_only;
            if (htu31_read_temperature(htu31_handle, &temperature_only) == ESP_OK) {
                // ESP_LOGI(TAG, "单独读取温度: %.2f °C", temperature_only);
            }
        } else {
            ESP_LOGE(TAG, "读取传感器数据失败: %s", esp_err_to_name(ret));
        }
        
        // 每5秒读取一次
        vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

// 设置手动校准值
static void set_manual_calibration(htu31_handle_t *htu31_handle)
{
    ESP_LOGI(TAG, "=== 设置手动校准值 ===");
    
    // 设置温度校准偏移量
    esp_err_t ret = htu31_set_temperature_offset(htu31_handle, TEMPERATURE_CALIBRATION_OFFSET);
    if (ret == ESP_OK) {
        ESP_LOGI(TAG, "温度校准偏移量设置成功: %.2f°C", TEMPERATURE_CALIBRATION_OFFSET);
    } else {
        ESP_LOGE(TAG, "温度校准偏移量设置失败");
    }
    
    // 设置湿度校准偏移量
    ret = htu31_set_humidity_offset(htu31_handle, HUMIDITY_CALIBRATION_OFFSET);
    if (ret == ESP_OK) {
        ESP_LOGI(TAG, "湿度校准偏移量设置成功: %.2f%%RH", HUMIDITY_CALIBRATION_OFFSET);
    } else {
        ESP_LOGE(TAG, "湿度校准偏移量设置失败");
    }
    
    ESP_LOGI(TAG, "校准公式: 实际值 = 传感器读数 - 校准偏移量");
    ESP_LOGI(TAG, "=== 校准设置完成 ===");
}

void app_main(void)
{
    htu31_handle_t htu31_handle = {0};
    
    ESP_LOGI(TAG, "HTU31温湿度传感器演示程序启动");

    // 初始化I2C
    ESP_LOGI(TAG, "初始化I2C总线...");
    ESP_ERROR_CHECK(i2c_master_init());
    ESP_LOGI(TAG, "I2C总线初始化完成");

    // 初始化HTU31传感器
    esp_err_t ret = init_htu31_sensor(&htu31_handle);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "HTU31传感器初始化失败，程序退出");
        return;
    }

    // 设置手动校准值
    set_manual_calibration(&htu31_handle);
    
    // 等待一段时间让用户查看校准结果
    ESP_LOGI(TAG, "校准设置完成，等待3秒后开始正常监测...");
    vTaskDelay(pdMS_TO_TICKS(3000));

    // 可选：开启加热器（用于除湿）
    // htu31_heater_enable(&htu31_handle, true);
    // vTaskDelay(pdMS_TO_TICKS(1000));
    // htu31_heater_enable(&htu31_handle, false);

    // 读取传感器数据
    ESP_LOGI(TAG, "开始读取校准后的传感器数据...");
    read_sensor_data(&htu31_handle);
}
